﻿
package com.greenantmall.version;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.RemoteViews;

import com.greenantmall.R;
import com.greenantmall.utils.Const;
import com.greenantmall.utils.iLog;
import com.greenantmall.version.DownloadManager.UpdateShared;

/**
 * 异步下载数据
 * 
 */
public class DownloadAsyncTask extends AsyncTask<String, Integer, String> {

    private DownloadCallback downCallBack;
    private HttpURLConnection urlConn;
    private Context mContext;
    private final static String TAG = "DownloadAsyncTask";
    private Notification notification = null;
    private Notification notificationSuc = null;
    private int progressCount = 0;
    private NotificationManager manager;
    private String apkPath = "";

    private static int NOTIFICATION_ID = 101;

    private long fileSize = 0;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {

            switch (msg.what) {
                case 0:
                case 1:
                    notification.contentView.setProgressBar(R.id.progressBar1, 100,
                            msg.arg1, false);
                    notification.contentView.setTextViewText(R.id.progressCount,
                            "蚂蚁商铺下载进度" + msg.arg1 + "%");
                    break;
                case 2:
				notification.contentView.setProgressBar(R.id.progressBar1, 100,
						msg.arg1, false);
				notification.contentView.setTextViewText(R.id.progressCount,
						"下载完成, 点击安装" + "100%");

				File destFile = new File(apkPath);
				try {
					String command = "chmod 777 " + destFile.getAbsolutePath();
					Log.i("zyl", "command = " + command);
					Runtime runtime = Runtime.getRuntime();

					Process proc = runtime.exec(command);
				} catch (IOException e) {
					Log.i("zyl", "chmod fail!!!!");
					e.printStackTrace();
				}
				
				try {
					String command = "chmod 777 " + Const.apkSavepath;
					Log.i("zyl", "command = " + command);
					Runtime runtime = Runtime.getRuntime();

					Process proc = runtime.exec(command);
				} catch (IOException e) {
					Log.i("zyl", "chmod fail!!!!");
					e.printStackTrace();
				}

				// 点击安装PendingIntent
				Intent installIntent = new Intent(Intent.ACTION_VIEW);
				installIntent.setDataAndType(Uri.fromFile(destFile),
						"application/vnd.android.package-archive");

				PendingIntent updatePendingIntent = PendingIntent.getActivity(
						mContext, 0, installIntent, 0);
				notification.defaults = Notification.DEFAULT_SOUND;// 铃声提醒
				notification.flags = Notification.FLAG_AUTO_CANCEL;
				notification.setLatestEventInfo(mContext, "蚂蚁商铺", "下载完成，请点击安装",
						updatePendingIntent);

                    break;

                case 3:
                    notification.contentView.setTextViewText(R.id.progressCount,
                            msg.obj.toString());

                    SharedPreferences sharedPreference = mContext
                            .getSharedPreferences(
                                    UpdateShared.SETTING_UPDATE_APK_INFO, 0);

                    Editor editor = sharedPreference.edit();

                    editor.putString(UpdateShared.CHECK_DATE, "");
                    editor.putString(UpdateShared.UPDATE_DATE, "");
                    editor.commit();

                    break;
            }

            manager.notify(NOTIFICATION_ID, notification);
        }
    };

    public DownloadAsyncTask(DownloadCallback downloadCallback,
            Context context, long fileSize) {
        this.downCallBack = downloadCallback;
        this.mContext = context;

        progressCount = 0;

        notification = new Notification(R.drawable.ic_launcher, "蚂蚁商铺下载",
                System.currentTimeMillis());

        notification.contentView = new RemoteViews(mContext.getPackageName(),
                R.layout.notification);

        notification.contentView.setProgressBar(R.id.progressBar1, 100, 0,
                false);
        notification.contentView.setTextViewText(R.id.progressCount, "蚂蚁商铺下载进度"
                + progressCount + "%");
        notification.flags = Notification.FLAG_AUTO_CANCEL;

        manager = (NotificationManager) mContext
                .getSystemService(Context.NOTIFICATION_SERVICE);
        this.fileSize = fileSize;
    }

    @Override
    protected void onPreExecute() {
        downCallBack.onDownloadPreare();
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... args) {
        String apkDownloadUrl = args[0]; // apk下载地址
        apkPath = args[1]; // apk在sd卡中的安装位置

        String result = doDownload(0, apkDownloadUrl);

        return result;
    }

    private String doDownload(int retryCount, String apkDownloadUrl) {
        String result = "";

        if (!IntentUtil.checkURL(apkDownloadUrl)) {
            result = "netfail";
        } else {
        	iLog.d("doDownload fileSize:"+fileSize+" apkDownloadUrl"+apkDownloadUrl);
            sendNotification(progressCount); // eric modify

            RandomAccessFile file = null;
            InputStream stream = null;
            HttpURLConnection connection = null;
            try {

                long downloaded = 0L;
                File apkFile = new File(apkPath);
                // 删除老版本文件
                clearDownloadFile(apkFile);

                // 若下载的临时文件存在，则将临时文件的大小作为断点下载
                if (apkFile.exists()) {
                    downloaded = apkFile.length();

                } else {

                    downloaded = 0L;

                    File apkParent = apkFile.getParentFile();
                    if (!apkParent.exists()) {
                        apkParent.mkdirs();
                    }

                    apkFile.createNewFile();

                }


                // 已经下载完成
                if (downloaded >= fileSize && fileSize > 0 && downloaded > 0) {
                    result = "success";

                    return result;
                }

                URL url = new URL(apkDownloadUrl);
                connection = (HttpURLConnection) url.openConnection();
                connection.setConnectTimeout(10 * 1000);
                connection.setReadTimeout(10 * 1000);
                connection.setRequestMethod("GET");
                connection.setRequestProperty("Accept-Language", "zh-CN");
                connection.setRequestProperty("Referer", url.toString());
                connection.setRequestProperty("Charset", "UTF-8");

                if (fileSize > 0) {
                    // 设置下载的断点
                    connection.setRequestProperty("Range", "bytes="
                            + downloaded + "-" + (fileSize - 1));
                } else {
                    downloaded = 0;
                }

                // 建立连接
                connection.connect();
                // 获得服务器的响应值
                int responseCode = connection.getResponseCode();
                if (connection.getResponseCode() != 200
                        && connection.getResponseCode() != 206) {

                    result = "netfail";

                    return result;
                }

                // 打开文件并定位至上次下载的断点处
                file = new RandomAccessFile(apkFile, "rw");
                file.seek(downloaded);

                // 得到目标的输入流
                stream = connection.getInputStream();
                long count = downloaded;
                int numread = 0;
                byte buf[] = new byte[1024];
                int i = 0;
                while (!downCallBack.onCancel()
                        && (numread = stream.read(buf)) != -1) {

                    // 先保存到本地，在更新进度
                    file.write(buf, 0, numread);

                    count += numread;
                    progressCount = (int) (((float) count / fileSize) * 100);

                    if (i > 100) {
                        sendNotification(progressCount);
                        i = 0;
                    }
                    i++;
                }


                if (count >= fileSize) {
                    sendNotification(100);
                    result = "success";
                } else {
                    result = "fail";
                }

            } catch (Exception e) {
                e.printStackTrace();

                if (retryCount > 10) {
                    result = "netfail";
                } else {
                    try {
                        if (file != null)
                            file.close();
                        if (stream != null)
                            stream.close();
                        if (connection != null)
                            connection.disconnect();

                    } catch (Exception ex) {
                        ex.printStackTrace();

                    }
                    result = doDownload(++retryCount, apkDownloadUrl);
                }

            } finally {
                try {
                    if (file != null)
                        file.close();
                    if (stream != null)
                        stream.close();
                    if (connection != null)
                        connection.disconnect();

                } catch (IOException e) {
                    e.printStackTrace();
                    // result = "fail";
                }
            }

        }
        return result;
    }

    private void clearDownloadFile(File apkFile) {

        try {
            File file = new File(Const.apkSavepath);

            File[] files = file.listFiles();

            if (files != null) {
                for (int i = 0; i < files.length; i++) {
                    if (apkFile != null) {
                        if (!apkFile.getName().equals(files[i].getName())) {
                            files[i].delete();

                        }

                    }

                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        // downCallBack.onChangeProgress(values[0]);
        super.onProgressUpdate(values);
    }

    // eric modify
    private void sendNotification(int progress) {
        Message message = Message.obtain();
        if (progress == 0) {
            message.what = 0;
        } else if (progress > 0 && progress < 99) {
            message.what = 1;
        } else {
            message.what = 2;
        }
        message.arg1 = progress;
        handler.sendMessage(message);
    }

    @Override
    protected void onPostExecute(String result) {
        if ("success".equals(result)) {
            sendNotification(100); // eric add
            // downCallBack.onCompleted(true, null);
        } else if ("netfail".equals(result)) {

            String code = "连接服务器失败，请稍后重试。";
            downCallBack.onCompleted(false, code);
            Message message = Message.obtain();
            message.what = 3;
            message.obj = code;
            handler.sendMessage(message);

        } else {
            String code = "版本更新失败，请稍后重试。";
            downCallBack.onCompleted(false, code);
            Message message = Message.obtain();
            message.what = 3;
            message.obj = code;
            handler.sendMessage(message);

        }
        super.onPostExecute(result);
    }

    @Override
    protected void onCancelled() {
        if (urlConn != null) {
            urlConn.disconnect();
        }
        super.onCancelled();
    }
}
